home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / wdj0797.zip / SDKANN.ZIP / SOURCE.ZIP / MSTATER.C < prev    next >
C/C++ Source or Header  |  1997-01-09  |  42KB  |  1,384 lines

  1. #include <assert.h>
  2. #include "anntater.h"
  3. #include <windowsx.h>
  4. #include <commdlg.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. extern void InitCheckList(HINSTANCE);
  9.  
  10. #define OutputDebugString(s)    (void)(s)
  11.  
  12. HWND    MainDlgWin;
  13.  
  14. int     MakeActive(HWND Window);
  15. void    MessagePump(int Time = 100);
  16.  
  17. int     InCopy      = FALSE;
  18. int     StopLoop    = FALSE;
  19.  
  20. UINT    WM_MSIN_RETURN  = RegisterWindowMessage("MSIN_RETURN");
  21.  
  22.  
  23. HWND    MsMainWin;
  24. HWND    MsTopicView;
  25.  
  26. size_t GetEnvVar(const char* Name, char* Buffer, size_t Size)
  27.     {
  28. #if defined(__WIN32__) || defined(__WIN32)
  29.     return GetEnvironmentVariable(Name, Buffer, Size);
  30. #else
  31.     const char* Env = GetDOSEnvironment();
  32.     while(Env && *Env)
  33.         {
  34.         const char* Found = strstr(Env, Name);
  35.         if(Found == Env && Found[strlen(Name)] == '=')
  36.             {
  37.             strcpy(Buffer, Found+strlen(Name)+1);
  38.             return strlen(Name);
  39.             }
  40.         }
  41.     return 0;
  42.  
  43. #endif
  44.     }
  45.  
  46.  
  47. HWND    GetRealParent(HWND Target)
  48.     {
  49. #if defined(__WIN32__) || defined(__WIN32)
  50.     return (HWND)GetWindowLong(Target, GWL_HWNDPARENT);
  51. #else
  52.     return (HWND)GetWindowWord(Target, GWW_HWNDPARENT);
  53. #endif
  54.     }
  55.  
  56. HWND    OpenMsAnno()
  57.     {
  58.     HWND    Anno = GetDlgItem(MsTopicView, 2);
  59.  
  60.     if(!Anno)
  61.         PostMessage(MsMainWin, WM_COMMAND, 35376, 0);
  62.     MessagePump(500);
  63.     Anno    = GetDlgItem(MsTopicView,2);        
  64.  
  65.     return Anno;
  66.     }
  67.  
  68.  
  69. /* Attributes
  70.  *  - window must be topmost
  71.  *  - window must be dialog
  72.  *  - window must contain child window with specific ID
  73.  *  - window must be contain certain text
  74.  *  - window must belong to certain app
  75.  */
  76.  
  77. HWND    FindTopOwnedWindow(HWND Owner, const char* Prefix, int Exact=FALSE)
  78.     {
  79. OutputDebugString("FindTopOwnedWindow  ");
  80. OutputDebugString(Prefix);
  81. OutputDebugString(" \n");
  82.  
  83.     assert(IsWindow(Owner));
  84.     HWND    Rover = GetDesktopWindow();
  85.     Rover   = GetWindow(Rover, GW_CHILD);
  86.     while(Rover)
  87.         {
  88.         HWND    Parent = (HWND)GetRealParent(Rover);
  89.         if(Parent == Owner)
  90.             {
  91.             char Title[256];
  92.             GetWindowText(Rover, Title, 255);
  93.             if(!Exact && !strncmp(Prefix, Title, strlen(Prefix)))
  94.                 return Rover;
  95.             else if(!strcmp(Prefix, Title))
  96.                 return Rover;
  97.             }
  98.         Rover   = GetWindow(Rover, GW_HWNDNEXT);
  99.         }
  100.     return 0;
  101.     }
  102.  
  103.  
  104. int     MB(const char* Msg)
  105.     {
  106.     return MessageBox(MainDlgWin, Msg, "MsTater", MB_OK);
  107.     }
  108.  
  109.  
  110. void    MessagePump2(HWND Dialog, int Time = 100)
  111.     {
  112.     int StopLoop = FALSE;
  113.     SetTimer(Dialog, 45, Time, 0);
  114.  
  115. EnableWindow(Dialog, FALSE);
  116.  
  117.     MSG Msg;
  118. while(!StopLoop)
  119.     while(PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE))
  120.         {
  121.         switch(Msg.message)
  122.             {
  123.             case    WM_KEYDOWN      :
  124.             case    WM_LBUTTONDOWN  :
  125.             case    WM_RBUTTONDOWN  :
  126.             case    WM_MBUTTONDOWN  :
  127.             case    WM_TIMER        :
  128.                 StopLoop    = TRUE;
  129.             }
  130.         GetMessage(&Msg, NULL, 0, 0);
  131.         DispatchMessage(&Msg);
  132.         }
  133.     KillTimer(Dialog, 45);
  134. EnableWindow(Dialog, TRUE);
  135.     }
  136.  
  137.  
  138. #if 1
  139.  
  140. void    MessagePump(int Time)
  141.     {
  142.     DWORD   StartTime = GetTickCount();
  143.     MSG Msg;
  144. while((GetTickCount() - StartTime) < Time)
  145.     while(PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE))
  146.         {
  147.         switch(Msg.message)
  148.             {
  149.             case    WM_KEYDOWN      :
  150.             case    WM_LBUTTONDOWN  :
  151.             case    WM_RBUTTONDOWN  :
  152.             case    WM_MBUTTONDOWN  :
  153.                 StopLoop    = TRUE;
  154.             }
  155.         GetMessage(&Msg, NULL, 0, 0);
  156.         DispatchMessage(&Msg);
  157.         }
  158.     }
  159.  
  160. #endif
  161.  
  162. int     PushButton(HWND Dialog, int ButtonId, int Post = FALSE)
  163.     {
  164.     int     Result  = FALSE;
  165.     HWND    Button  = GetDlgItem(Dialog, ButtonId);
  166.     if(Button)
  167.         {
  168.         if(Post)
  169.             {
  170.             PostMessage(Dialog, WM_COMMAND, ButtonId,
  171.                 MAKELONG(Button, BN_CLICKED));
  172.             MessagePump();
  173.             }
  174.         else
  175.             SendMessage(Dialog, WM_COMMAND, ButtonId,
  176.                 MAKELONG(Button, BN_CLICKED));
  177.         Result      = TRUE;
  178.         }
  179.     return Result;
  180.     }
  181.  
  182. #if 0
  183. int     CheckRadio(HWND Dialog, int FirstButton, int LastButton)
  184.     {
  185.     int     Result  = FALSE;
  186.     if(Button)
  187.         {
  188.         else
  189.             SendMessage(Dialog, WM_COMMAND, ButtonId,
  190.                 MAKELONG(Button, BM_SETCHECK));
  191.         Result      = TRUE;
  192.         }
  193.     return Result;
  194.     }
  195. #endif
  196.  
  197.  
  198.  
  199. // OpenMsSearch - open the search dialog in Developer Studio
  200. // we also make sure the full-text search property sheet is active
  201. HWND OpenMsSearch(HWND Dialog, int Complain = TRUE, int And=FALSE)
  202.     {
  203.     char Buffer[256];
  204.     HWND Search = GetWindow(GetDesktopWindow(), GW_CHILD);
  205.     while(Search)
  206.         {
  207.         GetWindowText(Search, Buffer, sizeof(Buffer)-1);
  208.         if(!strcmp(Buffer, "Search") && MsMainWin == GetWindow(Search, GW_OWNER))
  209.             break;
  210.         Search   = GetWindow(Search, GW_HWNDNEXT);
  211.         }
  212.     if(!Search)
  213.         {
  214.         if(Complain)
  215.             MessageBox(NULL, "Unable to open Search dialog [no child of main window]", "MsTater", MB_OK);
  216.         return 0;
  217.         }
  218.     assert(IsWindow(Search));
  219. //    MakeActive(Search);
  220. //    BringWindowToTop(Search);
  221.     GetWindowText(Search, Buffer, sizeof(Buffer)-1);
  222.     if(strcmp(Buffer, "Search"))
  223.         {
  224.         MessageBox(NULL, "Unable to open Search dialog [child title not 'Search']", Buffer, MB_OK);
  225.         return 0;
  226.         }
  227.     MessagePump2(Dialog);
  228.     HWND Prop = GetWindow(Search, GW_CHILD);
  229.     GetWindowText(Prop, Buffer, sizeof(Buffer)-1);
  230.     if(strcmp(Buffer, "Query"))
  231.         {
  232.         MessagePump2(Dialog, 1000);
  233.         Prop    = GetWindow(Search, GW_CHILD);
  234.         GetWindowText(Prop, Buffer, sizeof(Buffer)-1);
  235.         if(strcmp(Buffer, "Query"))
  236.             MessageBox(NULL, "Please click on the 'Query' tab in the Search dialog and then press my OK button", "MsTater", MB_OK);
  237.         Prop    = GetWindow(Search, GW_CHILD);
  238.         }
  239.     GetWindowText(Prop, Buffer, sizeof(Buffer)-1);
  240.     if(strcmp(Buffer, "Query"))
  241.         {
  242.         MessageBox(NULL, "Could not locate Query tab in Search Dialog", "MsTater", MB_OK);
  243.         return FALSE;
  244.         }
  245.     // push buttons the way we like...
  246.     if(And)
  247.         {
  248.         // subset == results of last query
  249.         CheckRadioButton(Prop, 0x01FF, 0x0202, 0x0201);
  250.         // Title and Contents
  251.         CheckRadioButton(Prop, 0x0209, 0x020A, 0x0209);
  252.         }
  253.     else
  254.         {
  255.         // Entire Contents
  256.         CheckRadioButton(Prop, 0x01FF, 0x0202, 0x01FF);
  257.         // Title only
  258.         CheckRadioButton(Prop, 0x0209, 0x020A, 0x020A);
  259.         }
  260.     MessagePump();
  261.  
  262.     return Prop;
  263.     }
  264.  
  265.  
  266. BOOL    EnableControl(HWND Dialog, int Id, int On)
  267.     {
  268.     HWND    Child = GetDlgItem(Dialog, Id);
  269.     if(Child != 0)
  270.         return EnableWindow(Child, On);
  271.     else
  272.         return FALSE;
  273.     }
  274.  
  275. typedef BOOL (WINAPI*SETFUNC)(HWND Window);
  276.  
  277. int     MakeActive(HWND Window)
  278.     {
  279. #if defined(__WIN32__) || defined(__WIN32)
  280.     SetForegroundWindow(Window)
  281. #else
  282.  
  283. #define USER() GetModuleHandle("USER")
  284.     static int Loaded = FALSE;
  285.     static SETFUNC SetForegroundWindow;
  286.  
  287.     assert(IsWindow(Window));
  288.  
  289.     if(!Loaded)
  290.         {
  291.         SetForegroundWindow = (SETFUNC)GetProcAddress(USER(),"SetForegroundWindow");
  292.         Loaded  = TRUE;
  293.         }
  294.     if(SetForegroundWindow)
  295.         SetForegroundWindow(Window);
  296.     else
  297.         SetActiveWindow(Window);
  298. #endif
  299.     MessagePump(250);
  300.     return TRUE;
  301.     }
  302. char    SelectedFile[512];
  303.  
  304. // name of main dialog box
  305. #define MAIN_DLG   "MainDialog"
  306.  
  307. HINSTANCE CurrentInstance;  // often need global for this
  308.  
  309. /*  GetHelpDialog() - locate a dialog belonging to the help window
  310.  *
  311.  *  Sometimes we need to find one of WinHelp's dialog windows.
  312.  *  This function locates a top-level window whose parent is the
  313.  *  WinHelp window. You can also specify the Id of a child window,
  314.  *  in case you need to distinguish between two WinHelp dialogs.
  315.  */
  316. HWND    GetHelpDialog(int ChildId=0)
  317.     {
  318.     HWND    Help = FindWindow("MS_WINHELP", NULL);
  319.     HWND    Rover = GetDesktopWindow();
  320.     Rover   = GetWindow(Rover, GW_CHILD);
  321.     while(Rover)
  322.         {
  323.         HWND    Parent = GetRealParent(Rover);
  324.         HWND    GrandParent = 0;
  325.         if(Parent)
  326.             GrandParent = GetRealParent(Parent);
  327.         if(Parent == Help || GrandParent == Help)
  328.             {
  329.             if(!ChildId || GetDlgItem(Rover, ChildId))
  330.                 return Rover;
  331.             }
  332.         Rover   = GetWindow(Rover, GW_HWNDNEXT);
  333.         }
  334.     return 0;
  335.     }
  336.  
  337.  
  338. #include <io.h>
  339. int WDJ_PathFind(const char *InPath, const char *File,
  340.                                     char *OutPath, int Maxlen)
  341.     {
  342.     /* sanity check */
  343.     if(InPath && *InPath)
  344.         {
  345.         // for each directory in the path
  346.         while(*InPath)
  347.             {
  348.             char    Dir[256];
  349.             const char*Rover = strchr(InPath, ';');
  350.             int Len = Rover ? (Rover - InPath) : strlen(InPath);
  351.             memcpy(Dir, InPath, Len);
  352.             Dir[Len]    = '\0';
  353.             strcat(Dir, "\\");
  354.             strcat(Dir, File);
  355.             if(access(Dir, 0) != -1)
  356.                 {
  357.                 if(OutPath && Maxlen)
  358.                     {
  359.                     strcpy(OutPath, Dir);
  360.                     return TRUE;
  361.                     }
  362.                 }
  363.             InPath += Len+1;
  364.             }
  365.         }
  366.     return FALSE;
  367.     }
  368.  
  369. const char* GetPath()
  370.     {
  371.     static char Path[256+1];
  372.     if(GetEnvVar("PATH", Path, sizeof(Path)))
  373.         return Path;
  374.     else
  375.         return 0;
  376.     }
  377.  
  378. /*  FindHelpFile - user selected new .hlp, try to locate it
  379.  *
  380.  *  When the user picks a different .hlp to annotate, this
  381.  *  function tries to locate that .hlp file. First, it tries
  382.  *  the last known path for that .hlp file, which would be
  383.  *  recorded in the .ini file. If that fails, it then searches
  384.  *  the DOS environment path. If that fails, then all the other
  385.  *  buttons are disabled except for the one that lets the user
  386.  *  tell us where the .hlp file is.
  387.  */
  388. int  FindHelpFile(HWND Dialog, const char*File)
  389.     {
  390.     int     Result = TRUE;
  391.     char    Found[512];
  392.     GetPrivateProfileString("AnnTater", File, "", Found, sizeof(Found), "wdj.ini");
  393.  
  394.     // if not found in .ini file
  395.     if(Found[0] == '\0')
  396.         {
  397.         const char*Search = GetPath();
  398.         if(!WDJ_PathFind(Search, File, Found, sizeof(Found)))
  399.             Result  = FALSE;
  400.         }
  401.     if(Result == TRUE)
  402.         {
  403.         EnableControl(Dialog, ID_COPY, TRUE);
  404.         EnableControl(Dialog, ID_SELECTALL, TRUE);
  405.         SetDlgItemText(Dialog, ID_HELP_PATH, Found);
  406.         strcpy(SelectedFile, Found);
  407.         }
  408.     else
  409.         {
  410.         EnableControl(Dialog, ID_COPY, FALSE);
  411.         EnableControl(Dialog, ID_SELECTALL, FALSE);
  412.         SetDlgItemText(Dialog, ID_HELP_PATH,
  413.             "<press Locate button to specify path for this file>");
  414.         }
  415.     return Result;
  416.     }
  417.  
  418.  
  419. // load RCDATA resource, assumes string terminated by 2 NULLs
  420. int     GetResource(const char *Name, char *Buffer)
  421.     {
  422.     int     Len;
  423.     char   *Data;
  424.     HGLOBAL Handle;
  425.     HRSRC   Pos = FindResource(CurrentInstance, Name, RT_RCDATA);
  426.     if(Pos == NULL)
  427.         return FALSE;
  428.     Handle  = LoadResource(CurrentInstance, Pos);
  429.     Data    = (char *)LockResource(Handle);
  430.     for(Len=0; Data[Len] || Data[Len+1]; ++Len)
  431.         ;
  432.     memcpy(Buffer, Data, Len+1);
  433.     UnlockResource(Handle);
  434.     FreeResource(Handle);
  435.     return Len;
  436.     }
  437.  
  438. char*   StrDup(const char* S)
  439.     {
  440.     size_t  Len     = strlen(S) + 1;
  441.     char* Result    = new char[Len];
  442.     if(Result)
  443.         memcpy(Result, S, Len);
  444.     return Result;
  445.     }
  446.  
  447. int     IsHelp32 = FALSE;
  448.  
  449. int     InitHelpVersion()
  450.     {
  451.     size_t  Len;
  452.     HINSTANCE Inst;
  453.     char    Path[512];
  454.     HWND    Help = FindWindow("MS_WINHELP", NULL);
  455.     Inst = GetWindowInstance(Help);
  456.     Path[0] = '\0';
  457.     GetModuleFileName(Inst, Path, sizeof(Path));
  458.     Len = strlen(Path);
  459.     /* 32-bit module name is "WINHLP32.EXE" */
  460.     if(Len >= 12 && Path[Len-6] == '3' && Path[Len-5] == '2')
  461.         IsHelp32    = TRUE;
  462.  
  463.     return TRUE;
  464.     }
  465.  
  466. int     WDJ_EmptyClipboard(void)
  467.     {
  468.     HWND ClipWin = GetDesktopWindow(); /* any window will do */
  469.  
  470.     if(OpenClipboard(ClipWin))
  471.         {
  472.         EmptyClipboard();
  473.         CloseClipboard();
  474.         return TRUE;
  475.         }
  476.     return FALSE;
  477.     }
  478.  
  479. int     WDJ_SetClipboardText(char *Buffer)
  480.     {
  481.     int     Result = FALSE;
  482.     HWND ClipWin = GetDesktopWindow(); /* any window will do */
  483.  
  484.     if(OpenClipboard(ClipWin))
  485.         {
  486.         size_t   Len = strlen(Buffer) + 1;
  487.         HGLOBAL  ClipData = GlobalAlloc(GHND, Len);
  488.         if(ClipData != 0)
  489.             {
  490.             char    *P = (char*)GlobalLock(ClipData);
  491.             strcpy(P, Buffer);
  492.             GlobalUnlock(ClipData);
  493.             if(SetClipboardData(CF_TEXT, ClipData))
  494.                 Result  = TRUE;
  495.             }
  496.         CloseClipboard();
  497.         }
  498.  
  499.     return Result;
  500.     }
  501.  
  502. int     WDJ_GetClipboardText(char *Buffer, UINT MaxSize)
  503.     {
  504.     int     Result = FALSE;
  505.     HWND ClipWin = GetDesktopWindow(); /* any window will do */
  506.  
  507.     if(OpenClipboard(ClipWin))
  508.         {
  509.         HGLOBAL  ClipData;
  510.         ClipData    = (HGLOBAL)GetClipboardData(CF_TEXT);
  511.         if(ClipData != NULL)
  512.             {
  513.             char *P     = (char*)GlobalLock(ClipData);
  514.             if(P != 0)
  515.                 {
  516.                 UINT  Len   = strlen(P) + 1;
  517.                 if(MaxSize > 0)
  518.                     {
  519.                     if(MaxSize < Len)
  520.                         Len = MaxSize;
  521.                     if(Len > 0)
  522.                         memcpy(Buffer, P, Len-1);
  523.                     Buffer[Len] = '\0';
  524.                     }
  525.                 Result  = TRUE;
  526.                 }
  527.             GlobalUnlock(ClipData);
  528.             }
  529.         CloseClipboard();
  530.         }
  531.  
  532.     return Result;
  533.     }
  534.  
  535.  
  536.  
  537.  
  538. //*********************************************************
  539.  
  540. class TTopic
  541.     {
  542. public:
  543.     TTopic() : RsrcId_(0) {}
  544.    ~TTopic() {}
  545.     int     Load(HINSTANCE Inst, int TopicNum);
  546.     int     IsFor(const char*FileName);
  547.  
  548.     int     GetFile(char* Buffer, int Max)
  549.         { return GetIt(0, Buffer, Max); }
  550.     int     GetDisplayTitle(char* Buffer, int Max)
  551.         { return GetIt(1, Buffer, Max); }
  552.     int     GetKeyword(char* Buffer, int Max)
  553.         { return GetIt(2, Buffer, Max); }
  554.     int     GetTitle(char* Buffer, int Max)
  555.         { return GetIt(3, Buffer, Max); }
  556.     int     GetText(char* Buffer, int Max)
  557.         { return GetIt(4, Buffer, Max); }
  558.     void    Clear() { RsrcId_ = 0; TopicNum_ = 0; }
  559. private:
  560.     int     GetIt(int Pos, char*Buffer, int Max);
  561.     HRSRC   RsrcId_;
  562.     int     TopicNum_;
  563.     };
  564.  
  565. TTopic   ThisTopic;
  566.  
  567. int     TTopic::Load(HINSTANCE Inst, int TopicId)
  568.     {
  569.     TopicNum_   = TopicId;
  570.     RsrcId_  = FindResource(Inst,
  571.         MAKEINTRESOURCE(TopicId), RT_RCDATA);
  572.     return RsrcId_ != NULL;
  573.     }
  574.  
  575. int     TTopic::IsFor(const char* /*FileName*/)
  576.     {
  577.     if(!RsrcId_)
  578.         return FALSE;
  579.     char    File[128];
  580.     GetFile(File, sizeof(File));
  581.     return strcmpi("win31wh.hlp", File);
  582.     }
  583.  
  584. int     TTopic::GetIt(int Pos, char* Out, int Max)
  585.     {
  586.     int Result = FALSE;
  587.     if(!RsrcId_)
  588.         return Result;
  589.     char*   Buffer = new char[1024*8];
  590.     if(Buffer)
  591.         {
  592.         if(GetResource(MAKEINTRESOURCE(TopicNum_), Buffer))
  593.             {
  594.             const char*Rover = Buffer;
  595.             while(Pos--)
  596.                 Rover = Rover + strlen(Rover)+1;
  597.             if(Out && Max > 0)
  598.                 {
  599.                 for(int i=0; i < Max && *Rover; ++i)
  600.                     *Out++  = *Rover++;
  601.                 *Out = '\0';
  602.                 Result  = TRUE;
  603.                 }
  604.             }
  605.         delete[] Buffer;
  606.         }
  607.     return Result;
  608.     }
  609.  
  610. //*********************************************************
  611.  
  612.  
  613.  
  614.  
  615. typedef BOOL (*DLGCMDHANDLER)(HWND Dialog, UINT Notify,
  616.                                int ControlId, HWND Control);
  617. BOOL    DialogCommand(DLGCMDHANDLER Handler, HWND Dialog,
  618.                                WPARAM Param1, LPARAM Param2)
  619.     {
  620.     UINT    Notify;
  621.     UINT    ControlId;
  622.     HWND    Control;
  623. #if defined(__WIN32__)
  624.     Notify      = HIWORD(Param1);
  625.     ControlId   = LOWORD(Param1);
  626.     Control     = (HWND)Param2;
  627. #else
  628.     Notify      = HIWORD(Param2);
  629.     ControlId   = Param1;
  630.     Control     = (HWND)LOWORD(Param2);
  631. #endif
  632.     return Handler(Dialog, Notify, (int)ControlId, Control);
  633.     }
  634.  
  635.  
  636. // FindHelp - locate a standalone helpfile window!
  637. HWND    FindHelp(void)
  638.     {
  639.     return FindWindow("MS_WINHELP", NULL);
  640.     }
  641.  
  642. int     LoadTitles(HWND Listbox, const char*File)
  643.     {
  644.     char    *Buffer = (char *)malloc(1024*16);
  645.     char    *Title  = Buffer;
  646.     SendMessage(Listbox, WM_SETREDRAW, 0, 0);
  647.     SendMessage(Listbox, LB_RESETCONTENT, 0, 0);
  648.     TTopic  Topic;
  649.  
  650.     for(int i=1; Topic.Load(CurrentInstance, i); ++i)
  651.         {
  652.         if(Topic.IsFor(File))
  653.             {
  654.             Topic.GetDisplayTitle(Title, 1024);
  655.             int Index = SendMessage(Listbox, LB_ADDSTRING, 0, (LPARAM)Title);
  656.             if(Index != CB_ERR)
  657.                 {
  658.                 ListBox_SetItemData(Listbox, Index, i);
  659.                 }
  660.             }
  661.         }
  662.     SendMessage(Listbox, WM_SETREDRAW, 1, 0);
  663.     free(Buffer);
  664.     return TRUE;
  665.     }
  666.  
  667.  
  668.  
  669. enum { CANCEL = 9, REPLACE = 10, APPEND = 11,
  670.        ASK = 12,   SKIP = 13 } Always=ASK;
  671.  
  672. #ifdef __BORLANDC__
  673. #   pragma  argsused
  674. #endif
  675. static BOOL OnClobberDialogCommand(HWND Dialog, UINT Notify,
  676.                                 int ControlId, HWND Control)
  677.     {
  678.     if(ControlId == IDCANCEL)
  679.         {
  680.         EndDialog(Dialog, Always = CANCEL);
  681.         return FALSE;
  682.         }
  683.     else if(ControlId == ID_SKIP)
  684.         {
  685.         EndDialog(Dialog, SKIP);
  686.         if(IsDlgButtonChecked(Dialog, ID_STOPASKING))
  687.             Always  = CANCEL;
  688.         return FALSE;
  689.         }
  690.     else if(ControlId == ID_REPLACE)
  691.         {
  692.         EndDialog(Dialog, REPLACE);
  693.         if(IsDlgButtonChecked(Dialog, ID_STOPASKING))
  694.             Always  = REPLACE;
  695.         }
  696.     else if(ControlId == ID_APPEND)
  697.         {
  698.         EndDialog(Dialog, APPEND);
  699.         if(IsDlgButtonChecked(Dialog, ID_STOPASKING))
  700.             Always  = APPEND;
  701.         }
  702.     return FALSE;
  703.     }
  704.  
  705.  
  706. BOOL CALLBACK __export ClobberDialog(HWND Dialog, UINT Message,
  707.                                WPARAM Param1, LPARAM Param2)
  708.     {
  709.     if(Message == WM_INITDIALOG)
  710.         {
  711.         return TRUE;
  712.         }
  713.     else if(Message == WM_COMMAND)
  714.         {
  715.         return DialogCommand(OnClobberDialogCommand,
  716.                              Dialog, Param1, Param2);
  717.         }
  718.     return FALSE; /* FALSE == we didn't process msg */
  719.     }
  720.  
  721. static HWND StartSearch(HWND Dialog, const char* Keyword, int And)
  722.     {
  723.  
  724.     // search dialog might already be open, try it
  725.     HWND Search = OpenMsSearch(Dialog, FALSE, And);
  726.     if(!Search)
  727.         {
  728.         PostMessage(MsMainWin, WM_COMMAND, 35329, 0);
  729.         int i;
  730.         for(i=0; i < 10 && !Search; ++i)
  731.             {
  732.             MessagePump2(Dialog);
  733.             Search  = OpenMsSearch(Dialog, i >= 9, And);
  734.             }
  735.         if(!Search)
  736.             return 0;
  737.         }
  738.  
  739.     assert(IsWindow(Search));
  740.  
  741.     // now we have the search dialog open to the Query tab.
  742.     // get the handle to the search text combobox
  743.     MessagePump();
  744.     HWND SearchCombo = GetDlgItem(Search, 0x01F5);
  745.     if(!SearchCombo)
  746.         {
  747.         MB("Could not locate search string combobox in search dialog!");
  748.         return 0;
  749.         }
  750.     assert(IsWindow(SearchCombo));
  751.  
  752.     SendMessage(SearchCombo, CB_INSERTSTRING, 0, (LPARAM)Keyword);
  753.  
  754.     SendMessage(SearchCombo, CB_SETCURSEL, 0, 0);
  755.  
  756.     // push Query button
  757.     assert(IsWindow(GetDlgItem(Search, 0x01FA)));
  758. OutputDebugString("about to push the search button\n");
  759.     PushButton(Search, 0x01FA, TRUE);
  760. OutputDebugString("pushed the search button\n");
  761.     return Search;
  762.     }
  763.  
  764.  
  765.  
  766. // GetQueryResults - return handle to window containing query results
  767.  
  768. static HWND GetQueryResults(HWND Dialog, char* Buffer, const char* Title)
  769.     {
  770.     // now have to wait for results of query
  771.     // 1) wait a second
  772.     MessagePump2(Dialog, 1000);
  773.     // while the "delay" dialog is up, just loop
  774.     int i;
  775.     for(i=0; FindTopOwnedWindow(MsMainWin, "Query", TRUE) && i < 30; ++i)
  776.         MessagePump(500);
  777.  
  778.     // now search for query results window
  779.     HWND ResultWin = FindTopOwnedWindow(MsMainWin, "Query Results");
  780.     for(i = 0; i < 40 && !ResultWin; ++i)
  781.         {
  782.         ResultWin = FindTopOwnedWindow(MsMainWin, "Query Results");
  783.         if(!ResultWin &&
  784.             (ResultWin=FindWindow("#32770", "Microsoft Developer Studio")) != 0)
  785.             {
  786.             PushButton(ResultWin, IDCANCEL);
  787.             MessagePump();
  788.             wsprintf(Buffer, "Could not locate '%s', skipping to next topic.",
  789.                 Title);
  790.             MB(Buffer);
  791.             return 0;
  792.             }
  793.         MessagePump();
  794.         }
  795.  
  796.     if(!ResultWin)
  797.         {
  798.         MB("Could not locate query results dialog box!");
  799.         return 0;
  800.         }
  801.     return ResultWin;
  802.     }
  803.  
  804.  
  805. // ShowTopic - display a given topic in the target help file
  806. static int ShowTopic(HWND Dialog, int LbIndex)
  807.     {
  808.     char Buffer[256];
  809.     assert(IsWindow(Dialog));
  810. //    MakeActive(MsMainWin);
  811. OutputDebugString("Enter ShowTopic()\n");
  812. SetWindowText(Dialog, "enter ShowTopic()");
  813. //    MakeActive(Dialog);
  814.     int Topic = 0x7FFF & (int)ListBox_GetItemData(
  815.         GetDlgItem(Dialog, ID_TOPICTITLES), LbIndex);
  816.     ThisTopic.Load(CurrentInstance, Topic);
  817.     char    Keyword[128], AndKeyword[128];
  818.     ThisTopic.GetKeyword(Keyword, sizeof(Keyword));
  819.     strlwr(Keyword);
  820.     char* And = strstr(Keyword, " and ");
  821.     if(And)
  822.         {
  823.         *And    = '\0';
  824.         strcpy(AndKeyword, And+5);
  825.         }
  826.     else
  827.         strcpy(AndKeyword, "");
  828.         
  829.     char    Title[128];
  830.     ThisTopic.GetTitle(Title, sizeof(Title));
  831.     HWND Search     = StartSearch(Dialog, Keyword, FALSE);
  832.     if(!Search)
  833.         return -1;
  834.     HWND ResultWin  = GetQueryResults(Dialog, Buffer, Title);
  835.     if(!ResultWin)
  836.         return 0;
  837.  
  838.     assert(IsWindow(ResultWin));
  839.  
  840.     GetWindowText(ResultWin, Buffer, sizeof(Buffer)-1);
  841.  
  842.     char *S = strchr(Buffer, '(');
  843.     int     NumTopics = 2;
  844.     if(S)
  845.         NumTopics   = atoi(S+1);
  846.     assert(NumTopics >= 1);
  847.     if(NumTopics > 1)
  848.         {
  849. OutputDebugString("NumTopics > 1 \n");
  850.         BringWindowToTop(ResultWin);
  851.         // if we have additional keywords to narrow the search
  852.         if(AndKeyword[0])
  853.             {
  854. OutputDebugString(" Doing additional search with:");
  855. OutputDebugString("\n");
  856.             // dismiss results window
  857.             SendMessage(ResultWin, WM_MSIN_RETURN, 0, 0);
  858.             Search = StartSearch(Dialog, AndKeyword, TRUE);
  859.             if(!Search)
  860.                 return -1;
  861.             ResultWin   = GetQueryResults(Dialog, Buffer, Title);
  862.             if(!ResultWin)
  863.                 return 0;
  864.             assert(IsWindow(ResultWin));
  865.             GetWindowText(ResultWin, Buffer, sizeof(Buffer)-1);
  866.  
  867.             char *S = strchr(Buffer, '(');
  868.             int     NumTopics = 2;
  869.             if(S)
  870.                 NumTopics   = atoi(S+1);
  871.             assert(NumTopics >= 1);
  872.             if(NumTopics == 1)
  873.                 {
  874.                 // Whew! additional keywords did narrow the search
  875.                 // send secret message to go to topic
  876.                 SendMessage(ResultWin, WM_MSIN_RETURN, 0, 0);
  877.                 return TRUE;
  878.                 }
  879.             }
  880.  
  881.         BringWindowToTop(Dialog);
  882.         MB("Please select the correct topic to annotate, then press Enter.");
  883.         // now see if result window is still there
  884.         ResultWin = FindTopOwnedWindow(MsMainWin, "Query Results");
  885.         if(ResultWin)
  886.             SendMessage(ResultWin, WM_MSIN_RETURN, 0, 0);
  887.         }
  888.     else
  889.         {
  890.         // cool, secret message to dismiss dialog
  891.         SendMessage(ResultWin, WM_MSIN_RETURN, 0, 0);
  892.         }
  893.     
  894.     // Finally! We think we have the topic displayed
  895.     return TRUE;
  896.  
  897.     }
  898.  
  899. void    DisplayItem(HWND Dialog, int Index)
  900.     {
  901.     HWND Listbox = GetDlgItem(Dialog, ID_TOPICTITLES);
  902.  
  903.     int TopicNum = 0x7FFF & SendDlgItemMessage(Dialog,
  904.         ID_TOPICTITLES, LB_GETITEMDATA, Index, 0);
  905.     ThisTopic.Load(CurrentInstance, TopicNum);
  906.  
  907.     /* set edit control text */
  908.     SendDlgItemMessage(Dialog, ID_TOPICTEXT,
  909.             EM_SETSEL, 1, MAKELPARAM(0,-1));
  910.     char*Buffer = new char[8*1024];
  911.     if(Buffer)
  912.         {
  913.         Buffer[0]   = '\0';
  914.         ThisTopic.GetText(Buffer, 8*1024);
  915.         SendDlgItemMessage(Dialog, ID_TOPICTEXT, EM_REPLACESEL,
  916.             0, (LPARAM)Buffer);
  917.         ThisTopic.GetTitle(Buffer, 8*1024);
  918.         SetDlgItemText(Dialog, ID_TOPIC_TITLE, Buffer);
  919.         ThisTopic.GetKeyword(Buffer, 8*1024);
  920.         SetDlgItemText(Dialog, ID_TOPIC_KEYWORD, Buffer);
  921.         delete[] Buffer;
  922.         }
  923.     SendDlgItemMessage(Dialog, ID_TOPICTEXT, EM_SETSEL, 0, 0);
  924.     SendDlgItemMessage(Dialog, ID_TOPICTEXT, EM_LINESCROLL, 0,
  925.         MAKELPARAM(-255, 0));
  926.  
  927.     }
  928.  
  929. void    CheckItem(HWND Dialog, int Item)
  930.     {
  931.     HWND Listbox = GetDlgItem(Dialog, ID_TOPICTITLES);
  932.  
  933.     // add a checkmark to this item
  934.     int Old = ListBox_GetItemData(Listbox, Item);
  935.     ListBox_SetItemData(Listbox, Item, Old|0x8000);
  936.     // make sure it is not selected
  937.     ListBox_SetSel(Listbox, FALSE, Item);
  938.     ListBox_SetTopIndex(Listbox, (Item < 4) ? 0 : Item - 4);
  939.     // schedule a redraw
  940.     InvalidateRect(Listbox, NULL, FALSE);
  941.     }
  942.  
  943. static BOOL    CopySelections(HWND Dialog)
  944.     {
  945.     char   *Buffer, *Text;
  946.     LRESULT Count;
  947.     int    *Items, i;
  948. //    HWND    Help    = FindHelp();
  949.     HWND    Listbox = GetDlgItem(Dialog, ID_TOPICTITLES);
  950.  
  951.     StopLoop    = FALSE;
  952.     Count       = SendDlgItemMessage(Dialog, ID_TOPICTITLES,
  953.                         LB_GETSELCOUNT, 0, 0);
  954.     if(Count == 0)
  955.         return FALSE;
  956.     Items   = (int *)malloc(sizeof(int *)*(int)Count);
  957.     if(!Items)
  958.         {
  959.         MessageBox(Dialog, "Out of memory!", "AnnTater", MB_OK);
  960.         return FALSE;
  961.         }
  962.     SendDlgItemMessage(Dialog, ID_TOPICTITLES,
  963.                        LB_GETSELITEMS, (WPARAM)Count, (LPARAM)Items);
  964.  
  965.     Buffer  = (char *)malloc(1024*16);
  966.     if(!Buffer)
  967.         {
  968.         MessageBox(Dialog, "Out of memory!", "AnnTater", MB_OK);
  969.         return FALSE;
  970.         }
  971.     Text    = (char *)malloc(1024*16);
  972.     if(!Text)
  973.         {
  974.         free(Buffer);
  975.         MessageBox(Dialog, "Out of memory!", "AnnTater", MB_OK);
  976.         return FALSE;
  977.         }
  978.     int j;
  979.     for(i= 0; i < Count && Always != CANCEL; ++i)
  980.         {
  981.         if(StopLoop)
  982.             break;
  983.         DisplayItem(Dialog, Items[i]);
  984.         int Status = ShowTopic(Dialog, Items[i]);
  985.         if(Status == FALSE)
  986.             continue;
  987.         else if(Status == -1)
  988.             break;
  989.         HWND AnnDlg = OpenMsAnno();
  990.  
  991.         assert(IsWindow(AnnDlg));
  992.  
  993.         // read in our annotation text
  994.         ThisTopic.GetText(Text, 1024*16);
  995.         // now get existing annotation text from window
  996.         Buffer[0]   = '\0';
  997.         SendMessage(AnnDlg, WM_GETTEXT, 1024*16, (LPARAM)Buffer);
  998.  
  999.         /* if annotation already exists */
  1000.         if(Buffer[0])
  1001.             {
  1002.             if(strstr(Buffer, Text))
  1003.                 {
  1004. //                PushButton(AnnDlg, IDCANCEL, TRUE);
  1005.                 CheckItem(Dialog, Items[i]);
  1006.                 continue;
  1007.                 }
  1008.             int Result  = Always;
  1009.             if(Always == ASK)
  1010.                 {
  1011.                 MakeActive(Dialog);
  1012.                 Result = DialogBox(CurrentInstance, "Clobber",
  1013.                                 AnnDlg, (DLGPROC)ClobberDialog);
  1014. SetWindowText(Dialog, "back from helper dialog");
  1015.                 }
  1016.             if(Result == CANCEL || Result == SKIP)
  1017.                 {
  1018. //                PushButton(AnnDlg, IDCANCEL, TRUE);
  1019.                 continue;
  1020.                 }
  1021.             else if(Result == APPEND)
  1022.                 ;
  1023.             else if(Result == REPLACE)
  1024.                 Buffer[0]   = '\0';
  1025.             }
  1026.         strcat(Buffer, Text);
  1027.         SendMessage(AnnDlg, EM_SETSEL, 0, MAKELPARAM(0, -1));
  1028.         SendMessage(AnnDlg, EM_REPLACESEL, 0, (LPARAM)Buffer);
  1029.         MessagePump();
  1030.         CheckItem(Dialog, Items[i]);
  1031.         }
  1032.     free(Text);
  1033.     free(Items);
  1034.     free(Buffer);
  1035.     StopLoop    = FALSE;
  1036.     return TRUE;
  1037.     }
  1038.  
  1039.  
  1040. HWND    WindowFromInstance(HINSTANCE Instance)
  1041.     {
  1042.     HWND Rover = GetWindow(GetDesktopWindow(), GW_CHILD);
  1043.  
  1044.     while(Rover)
  1045.         {
  1046.         if(Instance == (HINSTANCE)GetWindowInstance(Rover))
  1047.             return Rover;
  1048.         else
  1049.             Rover   = GetWindow(Rover, GW_HWNDNEXT);
  1050.         }
  1051.  
  1052.     return (HWND)0;
  1053.     }
  1054.  
  1055. static BOOL OnMainDialogCommand(HWND Dialog, UINT Notify,
  1056.                                 int ControlId, HWND Control)
  1057.     {
  1058.     if(ControlId == IDOK || ControlId == IDCANCEL)
  1059.         {
  1060.         EndDialog(Dialog, ControlId == IDOK);
  1061.         return FALSE;
  1062.         }
  1063.     else if(ControlId == ID_HELP && Notify == BN_CLICKED)
  1064.         {
  1065.         static char*Help =
  1066. "MsTater: The Windows Developer's Journal helpfile annotater.\r\n"
  1067. "Use at your own risk!\r\n\r\n"
  1068. "Select one or more "
  1069. "annotations (or press the Select All button). Then, "
  1070. "press Copy to install your selections in the InfoViewer "
  1071. "(then stand well back). You may want to back up your "
  1072. ".ano file before starting this process. ";
  1073.         MessageBox(Dialog, Help, "AnnTater", MB_OK);
  1074.         }
  1075.     else if(ControlId == ID_FIND_FILE && Notify == BN_CLICKED)
  1076.         {
  1077.         HWND    Combo = GetDlgItem(Dialog, ID_FILES);
  1078.         char    File[256];
  1079.         char    Key[128];
  1080.         int Index = ComboBox_GetCurSel(Combo);
  1081.         strcpy(File,
  1082.             (const char*)ComboBox_GetItemData(Combo, Index)
  1083.             );
  1084.         strcpy(Key, File);
  1085.         
  1086.         OPENFILENAME    DialogArgs;
  1087.  
  1088.         memset(&DialogArgs, 0, sizeof(DialogArgs));
  1089.         DialogArgs.lStructSize  = sizeof(DialogArgs);
  1090.         DialogArgs.hwndOwner    = Dialog;
  1091.         char    Filter[256];
  1092.         memset(Filter, 0, sizeof(Filter));
  1093.         strcpy(Filter, "Selected help file");
  1094.         strcpy(Filter+strlen(Filter)+1, File);
  1095.         DialogArgs.lpstrFilter  = Filter;
  1096.         DialogArgs.nFilterIndex = 1;
  1097.         char    Title[256];
  1098.         wsprintf(Title, "Locate selected .hlp file (%s)", File);
  1099.         DialogArgs.lpstrTitle   = Title;
  1100.         DialogArgs.lpstrFile    = File;
  1101.         DialogArgs.nMaxFile     = 256;
  1102.         DialogArgs.Flags        = OFN_FILEMUSTEXIST | OFN_SHOWHELP;
  1103.  
  1104.         if(GetOpenFileName(&DialogArgs))
  1105.             {
  1106.             WritePrivateProfileString("AnnTater", Key, File, "wdj.ini");
  1107.             strcpy(SelectedFile, File);
  1108.             PostMessage(Dialog, WM_COMMAND, ID_FILES, MAKELONG(
  1109.                 GetDlgItem(Dialog, ID_FILES), CBN_SELCHANGE));
  1110.             }
  1111.         }
  1112.     else if(ControlId == ID_FILES && Notify == CBN_SELCHANGE)
  1113.         {
  1114.         char    File[256];
  1115.         File[0] = '\0';
  1116.         int Index = ComboBox_GetCurSel(Control);
  1117.         if(Index != CB_ERR)
  1118.             {
  1119.             strcpy(File, 
  1120.                 (const char*)ComboBox_GetItemData(Control, Index)
  1121.                 );
  1122.             // new .hlp file selected, attempt to set path
  1123.             if(!FindHelpFile(Dialog, File))
  1124.                 return TRUE;
  1125.             LoadTitles(GetDlgItem(Dialog, ID_TOPICTITLES), File);
  1126.             SetDlgItemText(Dialog, ID_TOPIC_KEYWORD,    "");
  1127.             SetDlgItemText(Dialog, ID_TOPIC_TITLE,      "");
  1128.             SetDlgItemText(Dialog, ID_TOPICTEXT,        "");
  1129.             WinHelp(Dialog, SelectedFile, HELP_QUIT, 0);
  1130.             MessagePump();
  1131.             WinHelp(Dialog, SelectedFile, HELP_CONTENTS, 0);
  1132.             InitHelpVersion();
  1133.             MessagePump();
  1134.             MoveWindow(FindWindow("MS_WINHELP", NULL),
  1135.                 0, 0,
  1136.                 100 + GetSystemMetrics(SM_CXSCREEN)/3,
  1137.                 100 + GetSystemMetrics(SM_CYSCREEN)/3, TRUE);
  1138.             MakeActive(Dialog);
  1139.             }
  1140.         }
  1141.     else if(ControlId == ID_COPY)
  1142.         {
  1143.         Always = ASK;
  1144.         if(InCopy)
  1145.             {
  1146.             StopLoop    = TRUE;
  1147.             return TRUE;
  1148.             }
  1149.         InCopy  = TRUE;
  1150.         SetWindowText(Control, "Stop copy!");
  1151.         CopySelections(Dialog);
  1152.         SetWindowText(Control, "Copy");
  1153.         InCopy  = FALSE;
  1154.         SetWindowText(Dialog, "Windows Developer's Journal Annotater");
  1155.         MakeActive(Dialog);
  1156.         return FALSE;
  1157.         }
  1158.     else if(ControlId == ID_SELECTALL)
  1159.         {
  1160.         int Count = SendDlgItemMessage(Dialog, ID_TOPICTITLES,
  1161.                     LB_GETCOUNT, 0, 0);
  1162.         SendDlgItemMessage(Dialog, ID_TOPICTITLES, LB_SELITEMRANGE, 1,
  1163.             MAKELPARAM(0, Count-1));
  1164.         int Index = SendDlgItemMessage(Dialog, ID_TOPICTITLES,
  1165.                     LB_GETSELCOUNT, 0, 0);
  1166.         EnableControl(Dialog, ID_COPY,   Index != 0);
  1167.         return FALSE;
  1168.         }
  1169.     else if(ControlId == ID_TOPICTITLES)
  1170.         {
  1171. OutputDebugString(">>>>>>>>>>>ID_TOPICTITLES");
  1172.         /* if selection changes, update edit box */
  1173.         if(Notify == LBN_SELCHANGE)
  1174.             {
  1175. OutputDebugString("    >>>>>>>LBN_SELCHANGE");
  1176.             LRESULT Index;
  1177.             /* enable/disable buttons, if we have selections or not */
  1178.             Index = SendDlgItemMessage(Dialog, ID_TOPICTITLES,
  1179.                         LB_GETSELCOUNT, 0, 0);
  1180.             EnableControl(Dialog, ID_COPY,   Index != 0);
  1181.  
  1182.             if(Index != 0)
  1183.                 {
  1184.                 /* load edit control with text from sel with caret */
  1185.                 Index = SendDlgItemMessage(Dialog, ID_TOPICTITLES,
  1186.                             LB_GETCARETINDEX, 0, 0L);
  1187. //                ShowTopic(Dialog, Index);
  1188.                 SetWindowText(Dialog, "Windows Developer's Journal Annotater");
  1189.                 int TopicNum = 0x7FFF & SendDlgItemMessage(Dialog,
  1190.                     ID_TOPICTITLES, LB_GETITEMDATA, Index, 0);
  1191.                 ThisTopic.Load(CurrentInstance, TopicNum);
  1192. //                MakeActive(Dialog);
  1193.                 }
  1194.             else
  1195.                 ThisTopic.Clear();
  1196.             /* set edit control text */
  1197.             SendDlgItemMessage(Dialog, ID_TOPICTEXT,
  1198.                     EM_SETSEL, 1, MAKELPARAM(0,-1));
  1199.             char*Buffer = new char[8*1024];
  1200.             if(Buffer)
  1201.                 {
  1202.                 Buffer[0]   = '\0';
  1203.                 ThisTopic.GetText(Buffer, 8*1024);
  1204.                 SendDlgItemMessage(Dialog, ID_TOPICTEXT, EM_REPLACESEL,
  1205.                     0, (LPARAM)Buffer);
  1206.                 ThisTopic.GetTitle(Buffer, 8*1024);
  1207.                 SetDlgItemText(Dialog, ID_TOPIC_TITLE, Buffer);
  1208.                 ThisTopic.GetKeyword(Buffer, 8*1024);
  1209.                 SetDlgItemText(Dialog, ID_TOPIC_KEYWORD, Buffer);
  1210.                 delete[] Buffer;
  1211.                 }
  1212.             SendDlgItemMessage(Dialog, ID_TOPICTEXT, EM_SETSEL, 0, 0);
  1213.             }
  1214. OutputDebugString("<<<<<<<<<<<<<<<ID_TOPICTITLES\n");
  1215.         return FALSE;
  1216.         }
  1217.     return FALSE; /* FALSE == we didn't process the message */
  1218.     }
  1219.  
  1220. /* InitFileList - initialize combo-box of files.
  1221.  *
  1222.  *  Here we make a pass over all the annotations and
  1223.  *  form the list of the names of the files that are
  1224.  *  referred to by these annotations. The filenames
  1225.  *  are stored in a combobox.
  1226.  */
  1227. void    InitFileList(HWND Dialog, int ComboId)
  1228.     {
  1229.     HWND    Combo = GetDlgItem(Dialog, ComboId);
  1230.     int Index;
  1231.     Index   = ComboBox_AddString(Combo, "MFC (mfc30.hlp)");
  1232.     ComboBox_SetItemData(Combo, Index, "mfc30.hlp");
  1233.     Index   = ComboBox_AddString(Combo, "Win32 API (win32.hlp, api32.hlp)");
  1234.     ComboBox_SetItemData(Combo, Index, "win32.hlp");
  1235.     Index   = ComboBox_AddString(Combo, "Windows 3.1 API (win31wh.hlp)");
  1236.     ComboBox_SetItemData(Combo, Index, "win31wh.hlp");
  1237.     }
  1238.  
  1239. BOOL CALLBACK __export MainDialog(HWND Dialog, UINT Message,
  1240.                                WPARAM Param1, LPARAM Param2)
  1241.     {
  1242.     if(Message == WM_INITDIALOG)
  1243.         {
  1244.         MainDlgWin  = Dialog;
  1245.         LoadTitles(GetDlgItem(Dialog, ID_TOPICTITLES), 0);
  1246.         SetDlgItemText(Dialog, ID_TOPIC_KEYWORD,    "");
  1247.         SetDlgItemText(Dialog, ID_TOPIC_TITLE,      "");
  1248.         SetDlgItemText(Dialog, ID_TOPICTEXT,        "");
  1249.         return TRUE;
  1250.         }
  1251. #if 0
  1252.     else if(Message == WM_TIMER)
  1253.         {
  1254.         MakeActive(Dialog);
  1255.         KillTimer(Dialog, 1);
  1256.         BringWindowToTop(Dialog);
  1257.         SetActiveWindow(Dialog);
  1258.         SetFocus(Dialog);
  1259.         }
  1260. #endif
  1261.     else if(Message == WM_USER + 999)
  1262.         {
  1263.         MakeActive(Dialog);
  1264.         }
  1265.     else if(Message == WM_COMMAND)
  1266.         {
  1267.         return DialogCommand(OnMainDialogCommand,
  1268.                              Dialog, Param1, Param2);
  1269.         }
  1270.     else if(Message == WM_DESTROY && SelectedFile[0])
  1271.         WinHelp(Dialog, SelectedFile, HELP_QUIT, 0);
  1272.     return FALSE; /* FALSE == we didn't process msg */
  1273.     }
  1274.  
  1275.  
  1276. // FindMsWindows - locate handles to all the windows we care about
  1277. int    FindMsWindows()
  1278.     {
  1279.     char Buffer[1024];
  1280.     HWND Desk   = GetDesktopWindow();
  1281.     HWND Rover  = GetWindow(Desk, GW_CHILD);
  1282.     while(Rover)
  1283.         {
  1284.         GetWindowText(Rover, Buffer, sizeof(Buffer)-1);
  1285.         if(!strncmpi(Buffer, "Microsoft Developer Studio", 26))
  1286.             break;
  1287.         Rover   = GetWindow(Rover, GW_HWNDNEXT);
  1288.         }
  1289.     if(Rover == 0)
  1290.         {
  1291.         MessageBox(NULL, "Start Microsoft Developer Studio before running MsTater.", "MsTater", MB_OK);
  1292.         return FALSE;
  1293.         }
  1294.     if(!strstr(Buffer, "InfoViewer"))
  1295.         {
  1296.         MessageBox(NULL, "Open (and maximize) the InfoViewer window in Developer Studio before running MsTater.", "MsTater", MB_OK);
  1297.         return FALSE;
  1298.         }
  1299.     MsMainWin   = Rover;
  1300.  
  1301.     // Now we have to descend down a long tree to find the annotation edit window
  1302.     Rover       = GetWindow(MsMainWin, GW_CHILD);
  1303.     while(Rover)
  1304.         {
  1305.         GetClassName(Rover, Buffer, sizeof(Buffer)-1);
  1306.         if(!strcmpi(Buffer, "MDIClient"))
  1307.             break;
  1308.         Rover   = GetWindow(Rover, GW_HWNDNEXT);
  1309.         }
  1310.     if(Rover == 0)
  1311.         {
  1312.         MessageBox(NULL, "MsTater could not talk to Developer Studio. [missing MDIClient]", "MsTater", MB_OK);
  1313.         return FALSE;
  1314.         }
  1315.  
  1316.     Rover       = GetWindow(Rover, GW_CHILD);
  1317.     while(Rover)
  1318.         {
  1319.         GetWindowText(Rover, Buffer, sizeof(Buffer)-1);
  1320.         if(!strcmpi(Buffer, "InfoViewer Topic"))
  1321.             break;
  1322.         Rover   = GetWindow(Rover, GW_HWNDNEXT);
  1323.         }
  1324.     if(Rover == 0)
  1325.         {
  1326.         MessageBox(NULL, "MsTater could not talk to Developer Studio. [missing InfoViewer Topic window]", "MsTater", MB_OK);
  1327.         return FALSE;
  1328.         }
  1329.     Rover       = GetWindow(Rover, GW_CHILD);
  1330.     Rover       = GetWindow(Rover, GW_CHILD);
  1331.     while(Rover)
  1332.         {
  1333.         GetWindowText(Rover, Buffer, sizeof(Buffer)-1);
  1334.         if(!strcmpi(Buffer, "TopicParent"))
  1335.             break;
  1336.         Rover   = GetWindow(Rover, GW_HWNDNEXT);
  1337.         }
  1338.     if(Rover == 0)
  1339.         {
  1340.         MessageBox(NULL, "MsTater could not talk to Developer Studio. [missing TopicParent window]", "MsTater", MB_OK);
  1341.         return FALSE;
  1342.         }
  1343.  
  1344.  
  1345.     Rover       = GetWindow(Rover, GW_CHILD);
  1346.     while(Rover)
  1347.         {
  1348.         GetWindowText(Rover, Buffer, sizeof(Buffer)-1);
  1349.         if(!strcmpi(Buffer, "TopicView"))
  1350.             break;
  1351.         Rover   = GetWindow(Rover, GW_HWNDNEXT);
  1352.         }
  1353.     if(Rover == 0)
  1354.         {
  1355.         MessageBox(NULL, "MsTater could not talk to Developer Studio. [missing TopicView window]", "MsTater", MB_OK);
  1356.         return FALSE;
  1357.         }
  1358.     MsTopicView = Rover;
  1359.     if(!OpenMsAnno())
  1360.         {
  1361.         MessageBox(NULL, "MsTater could not talk to Developer Studio. [Could not open annotation window]", "MsTater", MB_OK);
  1362.         return FALSE;
  1363.         }
  1364.  
  1365.     return TRUE;
  1366.     }
  1367.  
  1368. #ifdef __BORLANDC__
  1369.     #pragma argsused
  1370. #endif
  1371. int WINAPI WinMain(HINSTANCE Instance, HINSTANCE Previous,
  1372.                    LPSTR CommandLine, int ShowCommand)
  1373.     {
  1374.     CurrentInstance     = Instance;
  1375.     InitCheckList(Instance);
  1376.     if(FindMsWindows())
  1377.         {
  1378.         DialogBox(Instance, MAIN_DLG, NULL, (DLGPROC)MainDialog);
  1379.         }
  1380.     return 0;
  1381.     }
  1382.  
  1383.  
  1384.